#ifndef COMMUNICATION_H
#define COMMUNICATION_H

#include <QObject>
#include <QQueue>
#include <QElapsedTimer>
#include <QJsonObject>
#include <QJsonArray>

class QextSerialPort;

class Communication : public QObject
{
    Q_OBJECT

public:
    enum SerialPortState {
        UnconnectedState,
        ConnectingState,
        ConnectedState,
        ClosingState
    };

public:
    class WaitReplyItem {
    public:
        quint8 sn() const
        {
            return m_packet.at(6);
        }
        quint8 cmd() const
        {
            return m_packet.at(5);
        }

    public:
        int m_repeatTimes;
        QElapsedTimer m_timer;
        QByteArray m_packet;
    };

public:
    explicit Communication(QObject *parent = nullptr);

protected:
    void timerEvent(QTimerEvent *event) override;

public slots:
    void connectToHost(const QString &portName);
    void disconnectFromHost();
    bool isValid() const;

    void onFuzzyPIDAdjustValue(float value);
    void onRequestInteraction();

    void onReadReady();

Q_SIGNALS:
    //!
    //! \brief aboutToProcessed
    //! \param command
    //! \param result
    //!
    void aboutToProcessed(int command, bool result);

    //!
    //! \brief disconnected
    //!
    void disconnected();

    //!
    //! \brief 握手交互完成
    //!
    void interactiveCompleted();

    //!
    //! \brief 温度值更改
    //! \param temperature
    //!
    void temperatureChanged(float temperature);

    //!
    //! \brief 通讯状态更改
    //!
    void stateChanged(int state);

private:
    void onParse1(QDataStream &in);
    void onParse2(QDataStream &in);
    void onParse3(QDataStream &in);

private:
    void addWaitReplyItem(const QByteArray &packet);
    bool extract(QByteArray &packet);
    void sendRegularACK(quint8 cmd, quint8 sn);

private:
    QextSerialPort *m_control;
    QElapsedTimer *m_timer;
    QList<WaitReplyItem*> m_list;
    int m_timeId = 0;
    SerialPortState m_state;
    quint8 m_serialNumber;
};

#endif // COMMUNICATION_H
